#include <bits/stdc++.h>
using namespace std;

/*
3350. 检测相邻递增子数组 II
已解答
中等
相关标签
premium lock icon
相关企业
提示
给你一个由 n 个整数组成的数组 nums ，请你找出 k 的 最大值，使得存在 两个 相邻 且长度为 k 的 严格递增 子数组。具体来说，需要检查是否存在从下标 a 和 b (a < b) 开始的 两个 子数组，并满足下述全部条件：

这两个子数组 nums[a..a + k - 1] 和 nums[b..b + k - 1] 都是 严格递增 的。
这两个子数组必须是 相邻的，即 b = a + k。
返回 k 的 最大可能 值。

子数组 是数组中的一个连续 非空 的元素序列。

 

示例 1：

输入：nums = [2,5,7,8,9,2,3,4,3,1]

输出：3

解释：

从下标 2 开始的子数组是 [7, 8, 9]，它是严格递增的。
从下标 5 开始的子数组是 [2, 3, 4]，它也是严格递增的。
这两个子数组是相邻的，因此 3 是满足题目条件的 最大 k 值。
示例 2：

输入：nums = [1,2,3,4,4,4,4,5,6,7]

输出：2

解释：

从下标 0 开始的子数组是 [1, 2]，它是严格递增的。
从下标 2 开始的子数组是 [3, 4]，它也是严格递增的。
这两个子数组是相邻的，因此 2 是满足题目条件的 最大 k 值。
 

提示：

2 <= nums.length <= 2 * 105
-109 <= nums[i] <= 109
*/

// 法一
class Solution {
public:
    int maxIncreasingSubarrays(vector<int>& nums) {
        int n = nums.size();
        int cnt = 1;       // 当前连续严格递增子数组的长度
        int precnt = 0;    // 上一个连续严格递增子数组的长度
        int ans = 0;       // 记录最大的k值
        
        for (int i = 1; i < n; ++i) {
            if (nums[i] > nums[i - 1]) {
                // 当前元素延续递增，更新当前递增长度
                ++cnt;
            } else {
                // 递增中断，将当前长度转为上一段长度，重置当前长度
                precnt = cnt;
                cnt = 1;
            }
            
            // 情况1：取上一段与当前段长度的最小值（两段相邻可各提供k长度）
            ans = max(ans, min(precnt, cnt));
            // 情况2：当前段长度的一半（同一段内可划分两个相邻k长度子数组）
            ans = max(ans, cnt / 2);
        }
        
        return ans;
    }
};
    

// 法二
class Solution {
public:
    int maxIncreasingSubarrays(vector<int>& nums) {
        int k = 1;          // 当前连续严格递增子数组的长度（至少为1）
        int len = nums.size();
        int result = 0;     // 存储最大有效k值
        int last = 0;       // 上一个完整递增子数组的长度
        
        for (int i = 0; i < len - 1; ++i) {
            if (nums[i] < nums[i + 1]) {
                // 当前元素延续递增，更新当前段长度
                ++k;
            } else {
                // 递增中断，计算两种可能的有效k：
                // 1. 上一段与当前段的最小值（两段相邻各提供k长度）
                // 2. 当前段自身可拆分的最大k（长度的一半）
                result = max(min(last, k), result);
                result = max(result, k / 2);
                
                last = k;    // 保存当前段作为下一轮的"上一段"
                k = 1;       // 重置当前段长度
            }
        }
        
        // 处理最后一个递增段（循环结束后未处理的情况）
        result = max(min(last, k), result);
        result = max(result, k / 2);
        
        return result;
    }
};
    